name: build

on:
  push:
    branches:
      - master
  pull_request:
    types: [opened, labeled, unlabeled, synchronize]

permissions:
  contents: read

env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4g -Dorg.gradle.daemon=false -Dkotlin.incremental=false"

jobs:
  publish:
    runs-on: ubuntu-latest
    if: github.repository == 'square/okhttp' && github.ref == 'refs/heads/master'

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Upload Artifacts
        run: ./gradlew clean publish --stacktrace
        env:
          ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.SONATYPE_NEXUS_USERNAME }}
          ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.SONATYPE_NEXUS_PASSWORD }}
          ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.ARTIFACT_SIGNING_PRIVATE_KEY }}

  validation:
    name: "Validation"
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: gradle/actions/wrapper-validation@v3
      - name: Validate Renovate
        uses: rinchsan/renovate-config-validator@v0.2.0
        with:
          pattern: '.github/renovate.json'

  checkjdk11:
    permissions:
      checks: write # for mikepenz/action-junit-report
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew check -PandroidBuild=true -PgraalBuild=true -x test -x test

  testopenjdk11:
    permissions:
      checks: write # for mikepenz/action-junit-report
    runs-on: ubuntu-latest

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=11

      - name: Publish Test Report
        if: github.repository == 'square/okhttp' && github.ref == 'refs/heads/master'
        uses: mikepenz/action-junit-report@v4
        with:
          report_paths: '**/build/test-results/*/TEST-*.xml'
          check_name: OpenJDK 11 Test Report

      - name: Publish Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: github.repository == 'square/okhttp' && github.ref == 'refs/heads/master'
        with:
          files: |
            **/build/test-results/*/TEST-*.xml

  testzulu11:
    runs-on: ubuntu-latest
    if: contains(github.event.pull_request.labels.*.name, 'zulu')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=11

  testopenjdk8:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions') || contains(github.event.pull_request.labels.*.name, 'renovate')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=8

  testopenjdk8alpn:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install Old JDK 8
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 8.0.242

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=8 -Dokhttp.platform=jdk8alpn -Dalpn.boot.version=8.1.13.v20181017 -Dorg.gradle.java.installations.paths=/opt/hostedtoolcache/Java_Adopt_jdk/8.0.242-8.1/x64

  testopenjsse:
    runs-on: ubuntu-latest
    if: contains(github.event.pull_request.labels.*.name, 'providers')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=8 -Dokhttp.platform=openjsse

  testconscrypt:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'conscrypt')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=conscrypt

  testbouncycastle:
    runs-on: ubuntu-latest
    if: contains(github.event.pull_request.labels.*.name, 'providers')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=bouncycastle

  testcorretto:
    runs-on: ubuntu-latest
    # TODO add master build after fixing all tests in CI
    if: contains(github.event.pull_request.labels.*.name, 'providers')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=corretto

  testopenjdk17:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions') || contains(github.event.pull_request.labels.*.name, 'renovate')


    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=17

  testopenjdk21:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'jdkversions') || contains(github.event.pull_request.labels.*.name, 'renovate')


    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 21

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dtest.java.version=21

  testwindows:
    runs-on: windows-latest
    # TODO add master build after fixing all tests in CI
    if: contains(github.event.pull_request.labels.*.name, 'windows')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Test
        run: ./gradlew test

  testgraal:
    runs-on: ubuntu-latest
    # TODO add master build after fixing all tests in CI
    if: contains(github.event.pull_request.labels.*.name, 'graal')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Build okcurl
        run: ./gradlew okcurl:nativeImage

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Build ConsoleLauncher
        run: ./gradlew -PgraalBuild=true native-image-tests:nativeImage

      - name: Run Checks
        run: ./native-image-tests/build/graal/ConsoleLauncher

  testandroid:
    runs-on: ubuntu-latest
    timeout-minutes: 30
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'android') || contains(github.event.pull_request.labels.*.name, 'renovate')

    strategy:
      fail-fast: false
      matrix:
        api-level:
          - 21
          - 29
          - 34

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Enable KVM group perms
        # https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Gradle cache
        run: ./gradlew -PandroidBuild=true :okhttp-android:test

      - name: AVD cache
        uses: actions/cache@v4
        id: avd-cache
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd-${{ matrix.api-level }}

      - name: Create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

      - name: Run Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          script: ./gradlew -PandroidBuild=true :okhttp-android:connectedCheck :android-test:connectedCheck
        env:
          API_LEVEL: ${{ matrix.api-level }}

      - name: Run Release Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          script: ./gradlew -PandroidBuild=true :android-test-app:connectedCheck
        env:
          API_LEVEL: ${{ matrix.api-level }}

  testloom:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/master' || contains(github.event.pull_request.labels.*.name, 'loom')

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 21

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v3

      - name: Run Checks
        run: ./gradlew test -Dokhttp.platform=loom -Dtest.java.version=21 -PcontainerTests=true


  testandroidregression:
    runs-on: ubuntu-latest
    timeout-minutes: 10
    if: contains(github.event.pull_request.labels.*.name, 'android-regression')

    strategy:
      fail-fast: false
      matrix:
        api-level:
          - 29
          - 34

    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 11

      - name: Configure JDK
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Enable KVM group perms
        # https://github.blog/changelog/2023-02-23-hardware-accelerated-android-virtualization-on-actions-windows-and-linux-larger-hosted-runners/
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm

      - name: Gradle cache
        uses: gradle/actions/setup-gradle@v3

      - name: AVD cache
        uses: actions/cache@v4
        id: avd-cache
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd-${{ matrix.api-level }}

      - name: Create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          force-avd-creation: false
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

      - name: Run Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: ${{ matrix.api-level == '34' && 'x86_64' || 'x86' }}
          script: ./gradlew -PandroidBuild=true :regression-test:connectedCheck
        env:
          API_LEVEL: ${{ matrix.api-level }}
